/* -*- C++ -*- */

//=============================================================================
/*
 * @author Feloweria <380374483@qq.com>
 * Copyright (C) Feloweria
 * 
 * $ID 2013-07-14 10:12:05 PM
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @version 1.0
 */
//=============================================================================

#ifndef FELOWRIA_DATE_TIME_INCLUDE
#define FELOWRIA_DATE_TIME_INCLUDE

#include "Base/Base.h"
#include "Base/TimeValue.h"

FELOWRIA_BEGIN

#define ONE_HUNDREAD_YEAR		100
#define FOUR_HUNDREAD_YEAR		400

enum
{
	YEAR_HUNDRED_NONE = -1,
	YEAR_FIRST_HUNDRED,
	YEAR_SECOND_HUNDRED,
	YEAR_THIRD_HUNDRED,
	YEAR_FOUTH_HUNDRED,
	YEAR_HUNDRED_END
};

enum
{
	YEAR_NONE = -1,
	YEAR_FIRST,
	YEAR_SECOND,
	YEAR_THIRD,
	YEAR_FOUTH,
	YEAR_END
};

const int32 FELOWRIA_DAY_YEAR[YEAR_END] = 
{
	365,
	365,
	365,
	366
};

const TimeValue FELOWRIA_TIME_YEAR[YEAR_END] = 
{
	TIME_ONE_DAY * FELOWRIA_DAY_YEAR[YEAR_FIRST],
	TIME_ONE_DAY * FELOWRIA_DAY_YEAR[YEAR_SECOND],
	TIME_ONE_DAY * FELOWRIA_DAY_YEAR[YEAR_THIRD],
	TIME_ONE_DAY * FELOWRIA_DAY_YEAR[YEAR_FOUTH],
};
	
enum 
{
	MONTH_NONE = -1,
	MONTH_JAN,
	MONTH_FEB,
	MONTH_MAR,
	MONTH_APR,
	MONTH_MAY,
	MONTH_JUN,
	MONTH_JUL,
	MONTH_AUG,
	MONTH_SEP,
	MONTH_OCT,
	MONTH_NOV,
	MONTH_DEC,
	MONTH_END
};

const  int32 FELOWRIA_DAY_LEAP_MONTH[MONTH_END] = {31,29,31,30,31,30,31,31,30,31,30,31};
const  int32 FELOWRIA_DAY_COMMON_MONTH[MONTH_END] = {31,28,31,30,31,30,31,31,30,31,30,31};

const  TimeValue FELOWRIA_TIME_LEAP_ONE_MONTH[MONTH_END] = 
{
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_JAN],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_FEB],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_MAR],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_APR],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_MAY],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_JUN],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_JUL],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_AUG],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_SEP],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_OCT],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_NOV],
	TIME_ONE_DAY * FELOWRIA_DAY_LEAP_MONTH[MONTH_DEC]
	
};

const  TimeValue FELOWRIA_TIME_COMMON_ONE_MONTH[MONTH_END] = 
{
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_JAN],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_FEB],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_MAR],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_APR],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_MAY],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_JUN],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_JUL],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_AUG],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_SEP],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_OCT],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_NOV],
	TIME_ONE_DAY * FELOWRIA_DAY_COMMON_MONTH[MONTH_DEC]
};

enum
{
	WEEK_DAY_NONE = -1,
	WEEK_DAY_SUN,
	WEEK_DAY_MON,
	WEEK_DAY_TUE,
	WEEK_DAY_WED,
	WEEK_DAY_THU,
	WEEK_DAY_FRI,
	WEEK_DAY_SAT,
	WEEK_DAY_END,
};

const  TimeValue FELOWRIA_TIME_ONE_DAY = TIME_ONE_DAY;
const  TimeValue FELOWRIA_TIME_ONE_HOUR = TIME_ONE_HOUR;
const  TimeValue FELOWRIA_TIME_ONE_MINUTE = TIME_ONE_MINUTE;
const  TimeValue FELOWRIA_TIME_ONE_SECOND = TIME_ONE_SECOND;
const  TimeValue FELOWRIA_TIME_ONE_MILLI_SECOND = TIME_ONE_MILLI_SECOND;
const  TimeValue FELOWRIA_TIME_ONE_MICRO_SECOND = TIME_ONE_MICRO_SECOND;
const  TimeValue FELOWRIA_TIME_ONE_NAO_SECOND = TIME_ONE_NAO_SECOND;

FELOWRIA_END

FELOWRIA_BEGIN

TimeValue  DLL_EXPORT CurTime();

FELOWRIA_END

FELOWRIA_BEGIN

class DLL_EXPORT DateTime
{
public:
	explicit DateTime(const TimeValue time_value = 0);
	
	DateTime(const int32 year,
			const int32 month,
			const int32 day,
			const int32 week_day,
			const int32 hour,
			const int32 minute,
			const int32 second,
			const int32 micro_second);
	
	DateTime(const DateTime& date_time);
public:
	~DateTime();
	
public:
	int32 Year() const;
	void Year(int32 year);
	void YearAlter(int32 value);
	
	int32 Month() const;
	void Month(int32 month);
	void MonthAlter(int32 value);
	
	int32 Day() const;
	void Day(int32 day);
	void DayAlter(int32 value);
	
	int32 WeekDay() const;
	
	int32 Hour() const;
	void Hour(int32 hour);
	void HourAlter(int32 value);
	
	int32 Minute() const;
	void Minute(int32 minute);
	void MinuteAlter(int32 value);
	
	int32 Second() const;
	void Second(int32 second);
	void SecondAlter(int32 value);
	
	int32 MicroSecond() const;	
	void MicroSecond(int32 micro_second);
	void MicroSecondAlter(int32 value);
	
public:
	bool Update();
	
	bool Set(const TimeValue time_value = 0);
	
	bool Set(const int32 year,
			const int32 month,
			const int32 day,
			const int32 week_day,
			const int32 hour,
			const int32 minute,
			const int32 second,
			const int32 micro_second);
	
public:
	DateTime& operator=(const DateTime& date_time);
	DateTime& operator=(const TimeValue time_value);
	
	DateTime& operator+=(const DateTime& date_time);
	DateTime& operator+=(const TimeValue time_value);
	
	DateTime operator+(const DateTime& date_time) const;
	DateTime operator+(const TimeValue time_value) const;
	
private:
	int32 year;
	int32 month;;
	int32 day;
	int32 week_day;
	
	int32 hour;
	int32 minute;
	int32 second;
	int32 micro_second;
	
private:
	TimeValue time;

};// class DateTime

FELOWRIA_END

#include "DateTime.inl"

#endif // FELOWRIA_DATE_TIME_INCLUDE
